package com.lee.single.config;

import com.lee.single.property.SecurityAndRedisProperties;
import com.lee.single.starter.redis.RedisComponent;
import com.lee.single.starter.redis.SecurityRedisComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 配置2个redis数据源，一个用于token验证，一个用于存储普通数据
 * @author Lee
 * @date 2020/8/12
 */
@Configuration
@EnableConfigurationProperties(value = SecurityAndRedisProperties.class)
public class RedisConfig {

    @Autowired
    private SecurityAndRedisProperties redisProperties;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {

        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisProperties.getRedis().getHost(), redisProperties.getRedis().getPort());
        configuration.setDatabase(redisProperties.getRedis().getDatabase());
        configuration.setPassword(redisProperties.getRedis().getPassword());

        return new LettuceConnectionFactory(configuration);
    }

    @Bean
    public RedisConnectionFactory tokenRedisConnectionFactory() {

        RedisStandaloneConfiguration configuration;
        if (redisProperties.getRedisSecurity() == null) {
            configuration = new RedisStandaloneConfiguration(redisProperties.getRedis().getHost(), redisProperties.getRedis().getPort());
            configuration.setDatabase(8);
            configuration.setPassword(redisProperties.getRedis().getPassword());
        } else {
            configuration = new RedisStandaloneConfiguration(redisProperties.getRedisSecurity().getHost(), redisProperties.getRedisSecurity().getPort());
            configuration.setDatabase(redisProperties.getRedisSecurity().getDatabase());
            configuration.setPassword(redisProperties.getRedisSecurity().getPassword());
        }

        return new LettuceConnectionFactory(configuration);
    }

    /**
     * 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
     */
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, String> redisTemplate() {

        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // Value可设置为Serializable，使用GenericJackson2JsonRedisSerializer序列化器
        // 不使用对象序列化器的原因是序列化器存入数据时写入了转换对象的绝对信息，如@class:xx.xx.Obj
        // 项目必须有对应的entity才能转换，否则会异常，不适用于多服务
        // 而使用string在数据取出时通过objectMapper指定class来转换对象相对实用
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    /**
     * 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
     */
    @Bean(name = "tokenRedisTemplate")
    public RedisTemplate<String, String> tokenRedisTemplate() {

        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(tokenRedisConnectionFactory());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public SecurityRedisComponent securityRedisComponent() {

        return new SecurityRedisComponent();
    }

    @Bean
    public RedisComponent redisComponent() {

        return new RedisComponent();
    }

}
